<?php

/**
 * Class for rendering a table element.
 *
 * @author Ian Clarence <ian.clarence@gmail.com>
 */
class ViewTable extends ViewHtmlElement {

    /**
     * The table rows.
     *
     * @var array
     */
    private $tr = array();

    /**
     * The table head.
     *
     * @var string
     */
    private $thead;

    /**
     * The table body.
     *
     * @var string
     */
    private $tbody;

    /**
     * Array assigning classes to columns (e.g. "hidden").
     *
     * @var array
     */
    private $columnClass = array();

    /**
     * Array assigning classes to rows in the same way.
     *
     * @var array
     */
    private $rowClass = array();

    /**
     * The constructor.
     *
     * The $data parameter contains the contents of each cell of the table,
     * either as a string, or as inner HTML: an array of elements.
     *
     * @param array $fields
     */
    public function __construct(array $fields = array()) {

        $fields["key"] = "table";
        $fields["first_row_is_head"] = isset($fields["first_row_is_head"]) ? $fields["first_row_is_head"] : TRUE;
        $fields["data"] = isset($fields["data"]) ? $fields["data"] : array();

        parent::__construct($fields);

        if (isset($this->fields["border"])) {
            $this->setAttribute("border", $this->getBorder());
        }

        if (isset($this->fields["cellpadding"])) {
            $this->setAttribute("cellpadding", $this->getCellpadding());
        }

        if (isset($this->fields["cellspacing"])) {
            $this->setAttribute("cellspacing", $this->getCellspacing());
        }

        if (isset($this->fields["width"])) {
            $this->setAttribute("width", $this->getWidth());
        }

    }

    /**
     * Table rows
     */
    private function getRows() {
        if (count($this->fields["data"]) > 0) {
            foreach ($this->getData() as $key => $row) {
                $this->tr[$key] = ViewHtmlElement::elementInit("tr");
                $this->tr[$key]->setId($key);
                $this->tr[$key]->addOddOrEvenClass($key);
                $this->tr[$key]->innerHtml = $this->getColumns($row, $key);
                if (count($this->rowClass) > 0) {
                    foreach ($this->rowClass as $rowNumber => $className) {
                        if ($rowNumber == $key) {
                            $this->tr[$key]->addClass($className);
                        }
                    }
                }
            }
        }
    }

    /**
     * Table columns.
     *
     * @param array $row
     * @param int $rowNumber
     * @return array $td
     */
    private function getColumns($row, $rowNumber) {
        $td = array();
        if (is_array($row)) {
            if (count($row) > 0) {
                foreach ($row as $key => $column) {
                    $td[$key] = ViewHtmlElement::elementInit(($rowNumber == 0 && $this->getFirstRowIsHead()) ? "th" : "td");
                    $td[$key]->setId($key);
                    $td[$key]->addOddOrEvenClass($key);
                    if (is_array($column)) {
                        $td[$key]->innerHtml = $column;
                    }
                    else {
                        $td[$key]->addText($column);
                    }
                    if (count($this->columnClass) > 0) {
                        foreach ($this->columnClass as $columnNumber => $className) {
                            if ($columnNumber == $key) {
                                $td[$key]->addClass($className);
                            }
                        }
                    }
                }
                return $td;
            }
        }
        else {
            $td[0] = ViewHtmlElement::elementInit("td");
            $td[0]->addText($row);
            return $td;
        }
    }

    /**
     * Table head
     */
    private function fetchTableHead() {
        if ($this->getFirstRowIsHead()) {
            $this->thead = $this->tr[0]->encapsulate("thead");
        }
    }

    /**
     * Table body
     */
    private function fetchTableBody() {
        $rowsInBody = $this->tr;
        if ($this->getFirstRowIsHead()) {
            $firstRow = array_shift($rowsInBody);
        }
        $this->tbody = ViewHtmlElement::elementInit("tbody");
        $this->tbody->innerHtml = $rowsInBody;
    }

    /**
     * Setting a whole column "$columnNumber" to a class "$className".
     *
     * @param int $columnNumber
     * @param string $className
     */
    public function addClassToColumn($columnNumber, $className) {
        $this->columnClass[$columnNumber] = $className;
    }

    /**
     * Setting a whole row "$rowNumber" to a class "$className".
     *
     * @param int $rowNumber
     * @param string $className
     */
    public function addClassToRow($rowNumber, $className) {
        $this->rowClass[$rowNumber] = $className;
    }

    /**
     * Viewing
     */
    public function view() {
        $this->getRows();
        if ($this->getFirstRowIsHead()) {
            $this->fetchTableHead();
            $this->addInnerHtml($this->thead);
        }
        $this->fetchTableBody();
        $this->addInnerHtml($this->tbody);
        return parent::view();
    }

}